package com.innovation.ic.cc.web.controller.cc;

import com.innovation.ic.b1b.framework.util.StringUtils;
import com.innovation.ic.cc.base.model.cc.MapUserRole;
import com.innovation.ic.cc.base.model.cc.MenuTree;
import com.innovation.ic.cc.base.pojo.constant.model.MenuSelected;
import com.innovation.ic.cc.base.pojo.enums.MenuFirstEnum;
import com.innovation.ic.cc.base.pojo.variable.ApiResult;
import com.innovation.ic.cc.base.pojo.variable.AuthenticationUser;
import com.innovation.ic.cc.base.pojo.variable.ServiceResult;
import com.innovation.ic.cc.base.pojo.variable.menu.Menu;
import com.innovation.ic.cc.base.vo.menu.MenuTreeAndUserRoleVo;
import com.innovation.ic.cc.base.vo.menu.MenuTreeVo;
import com.innovation.ic.cc.web.controller.AbstractController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 菜单API
 */
@Api(value = "菜单API", tags = "MenuTreeController")
@RestController
@RequestMapping("/api/v1/menuTree")
public class MenuTreeController extends AbstractController {
    private static final Logger log =  LoggerFactory.getLogger(MenuTreeController.class);

    /**
     * 系统管理-职位管理-职位新增：主账号创建新角色时需要展示的菜单树形目录（不包括账号管理和角色管理），初始时没有任何选项被选中
     *
     * @param request
     * @param response
     * @return
     */
//    @HystrixCommand
    @ApiOperation(value = "系统管理-职位管理-职位新增：主账号创建新角色时需要展示的菜单树形目录（不包括账号管理和角色管理），初始时没有任何选项被选中")
    @RequestMapping(value = "/showMenuForAddRole", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
    @ResponseBody
    public ResponseEntity<ApiResult<MenuTree>> showMenuForAddRole(HttpServletRequest request, HttpServletResponse response) {

        ServiceResult<MenuTree> serviceResult = new ServiceResult<>();

        ApiResult<MenuTree> apiResult = new ApiResult<>();
        apiResult.setSuccess(Boolean.TRUE);
        apiResult.setCode(HttpStatus.OK.value());
        apiResult.setMessage(ServiceResult.SELECT_SUCCESS);
        apiResult.setResult(menuHandler.createSubAccountPersonnelMenuTree());
        return new ResponseEntity<>(apiResult, HttpStatus.OK);
    }

    @ApiOperation(value = "系统管理-人员管理-权限设置：主账号给新角色时设置权限管理需要展示的菜单树形目录（不包括角色管理，只包含人员管理查看权限），初始时没有任何选项被选中")
    @RequestMapping(value = "/showMenuForSetRole/{isManager}", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "isManager", value = "是否是经理: true 表示经理,false 表示员工", dataType = "Boolean", required = true)
    })
    @ResponseBody
    public ResponseEntity<ApiResult<MenuTree>> showMenuForSetRole(@PathVariable("isManager") Boolean isManager, HttpServletRequest request, HttpServletResponse response) {
        ServiceResult<MenuTree> serviceResult = new ServiceResult<>();

        ApiResult<MenuTree> apiResult = new ApiResult<>();
        apiResult.setSuccess(Boolean.TRUE);
        apiResult.setCode(HttpStatus.OK.value());
        apiResult.setMessage(ServiceResult.SELECT_SUCCESS);
        if (isManager) {
            apiResult.setResult(menuHandler.createSubAccountManagerMenuTree());
        } else {
            apiResult.setResult(menuHandler.createSubAccountPersonnelMenuTree());
        }

        return new ResponseEntity<>(apiResult, HttpStatus.OK);
    }

    /**
     * 系统管理-账号管理-权限设置-确定：添加用户和菜单的关系（先删除旧的关系，再添加新的关系）
     *
     * @param request
     * @param response
     * @return
     */
//    @HystrixCommand
    @ApiOperation(value = "系统管理-账号管理-权限设置-确定：添加用户和菜单的关系（先删除旧的关系，再添加新的关系）")
    @ApiImplicitParam(name = "menuTreeVo", value = "菜单树", required = true, dataType = "MenuTreeVo")
    @RequestMapping(value = "/saveOrUpdateMenuTree", method = RequestMethod.POST, produces = {"application/json; charset=utf-8"})
    @ResponseBody
    public ResponseEntity<ApiResult<MenuTree>> saveOrUpdateMenuTree(@RequestBody MenuTreeVo menuTreeVo, HttpServletRequest request, HttpServletResponse response) {
        ApiResult<MenuTree> apiResult;

        if (null == menuTreeVo) {
            String message = "调用接口【/api/v1/menuTree/saveOrUpdateMenuTree时，参数menuTreeVo不能为空";
            log.warn(message);
            apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.FALSE);
            apiResult.setCode(HttpStatus.BAD_REQUEST.value());
            apiResult.setMessage(message);
            return new ResponseEntity<>(apiResult, HttpStatus.BAD_REQUEST);
        }

        AuthenticationUser authenticationUser = this.getAuthenticationUser(request);
        if (null == authenticationUser) {
            apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.FALSE);
            apiResult.setCode(ApiResult.TOKEN_ILLEGAL_EXPIRE);
            return new ResponseEntity(apiResult, HttpStatus.UNAUTHORIZED);
        }

        MenuTree menuTree = menuHandler.menuTreeVoToMenuTree(menuTreeVo, authenticationUser.getId());
        ServiceResult<MenuTree> serviceResult = menuTreeService.saveOrUpdateMenuTree(menuTree);

        apiResult = new ApiResult<>();
        apiResult.setSuccess(serviceResult.getSuccess());
        apiResult.setCode(HttpStatus.OK.value());
        apiResult.setMessage(serviceResult.getMessage());
        apiResult.setResult(serviceResult.getResult());
        return new ResponseEntity<>(apiResult, HttpStatus.OK);
    }

    /**
     * 系统管理-账号管理-权限设置-确定：添加用户和菜单还有角色的关系（先删除旧的关系，再添加新的关系）
     *
     * @param request
     * @param response
     * @return
     */
//    @HystrixCommand
    @ApiOperation(value = "系统管理-账号管理-权限设置-确定：添加用户和菜单还有角色的关系（先删除旧的关系，再添加新的关系）")
    @ApiImplicitParam(name = "menuTreeAndUserRoleVo", value = "菜单和角色", required = true, dataType = "MenuTreeAndUserRoleVo")
    @RequestMapping(value = "/saveOrUpdateMenuTreeAndRole", method = RequestMethod.POST, produces = {"application/json; charset=utf-8"})
    @ResponseBody
    public ResponseEntity<ApiResult<MenuTree>> saveOrUpdateMenuTreeAndRole(@RequestBody MenuTreeAndUserRoleVo menuTreeAndUserRoleVo, HttpServletRequest request, HttpServletResponse response) {
        ApiResult<MenuTree> apiResult;

        if (null == menuTreeAndUserRoleVo) {
            String message = "调用接口【/api/v1/menuTree/saveOrUpdateMenuTreeAndRole时，参数menuTreeAndUserRoleVo不能为空";
            log.warn(message);
            apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.FALSE);
            apiResult.setCode(HttpStatus.BAD_REQUEST.value());
            apiResult.setMessage(message);
            return new ResponseEntity<>(apiResult, HttpStatus.BAD_REQUEST);
        }

        AuthenticationUser authenticationUser = this.getAuthenticationUser(request);
        if (null == authenticationUser) {
            apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.FALSE);
            apiResult.setCode(ApiResult.TOKEN_ILLEGAL_EXPIRE);
            return new ResponseEntity(apiResult, HttpStatus.UNAUTHORIZED);
        }
        //添加用户和角色关系
        List<MapUserRole> mapUserRoles = menuTreeAndUserRoleVo.getRoleIdList().stream().map(s -> {
            MapUserRole mapUserRole = new MapUserRole();
            mapUserRole.setUserId(menuTreeAndUserRoleVo.getUserId());
            mapUserRole.setRoleId(s);
            return mapUserRole;
        }).collect(Collectors.toList());

        ServiceResult<Boolean> serviceResultRole = mapUserRoleService.saveOrUpdateMapUserRoleList(mapUserRoles);
        if (!serviceResultRole.getSuccess()) {
            String message = "调用接口【/api/v1/menuTree/saveOrUpdateMenuTreeAndRole时，保存用户和角色信息失败";
            log.warn(message);
            apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.FALSE);
            apiResult.setCode(HttpStatus.BAD_REQUEST.value());
            apiResult.setMessage(message);
            return new ResponseEntity<>(apiResult, HttpStatus.BAD_REQUEST);
        }
        //添加用户和菜单关系
        MenuTree menuTree = menuHandler.menuTreeAndUserRoleVoToMenuTree(menuTreeAndUserRoleVo, authenticationUser.getId());
        ServiceResult<MenuTree> serviceResult = menuTreeService.saveOrUpdateMenuTree(menuTree);
        apiResult = new ApiResult<>();
        apiResult.setSuccess(serviceResult.getSuccess());
        apiResult.setCode(HttpStatus.OK.value());
        apiResult.setMessage(serviceResult.getMessage());
        apiResult.setResult(serviceResult.getResult());
        return new ResponseEntity<>(apiResult, HttpStatus.OK);
    }

    /**
     * 系统管理-账号管理-权限设置。根据子账号id，展示对应的菜单权限
     *
     * @param request
     * @param response
     * @return
     */
//    @HystrixCommand
    @ApiOperation(value = "系统管理-账号管理-权限设置。根据子账号id，展示对应的菜单权限")
    @ApiImplicitParam(name = "userId", value = "用户账号", required = true, dataType = "String")
    @RequestMapping(value = "/findByUserId/{userId}", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
    @ResponseBody
    public ResponseEntity<ApiResult<MenuTree>> findByUserId(@PathVariable("userId") String userId, HttpServletRequest request, HttpServletResponse response) {
        if (!StringUtils.validateParameter(userId)) {
            String message = "调用接口【/api/v1/menuTree/findByUserId，参数userId不能为空";
            log.warn(message);
            ApiResult<MenuTree> apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.FALSE);
            apiResult.setCode(HttpStatus.BAD_REQUEST.value());
            apiResult.setMessage(message);
            return new ResponseEntity<>(apiResult, HttpStatus.BAD_REQUEST);
        }

        ServiceResult<MenuTree> serviceResult = menuTreeService.findByUserId(userId);

        ApiResult<MenuTree> apiResult = new ApiResult<>();
        apiResult.setSuccess(serviceResult.getSuccess());
        apiResult.setCode(HttpStatus.OK.value());
        apiResult.setMessage(serviceResult.getMessage());
        apiResult.setResult(serviceResult.getResult());
        return new ResponseEntity<>(apiResult, HttpStatus.OK);
    }

    /**
     * 左侧菜单使用：根据用户id，查找页面左侧对应的菜单列表。主账号返回所有菜单列表，子账号根据权限返回对应的菜单列表。包括三级目录
     *
     * @param request
     * @param response
     * @return
     */
//    @HystrixCommand
    @ApiOperation(value = "左侧菜单使用：根据用户id，查找对应的菜单列表。主账号返回所有菜单列表，子账号根据权限返回对应的菜单列表。包括三级目录")
    @RequestMapping(value = "/findByLoginUserId", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
    @ResponseBody
    public ResponseEntity<ApiResult<MenuTree>> findByLoginUserId(HttpServletRequest request, HttpServletResponse response) {
        ApiResult<MenuTree> apiResult;

        AuthenticationUser authenticationUser = this.getAuthenticationUser(request);
        if (null == authenticationUser) {
            apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.FALSE);
            apiResult.setCode(ApiResult.TOKEN_ILLEGAL_EXPIRE);
            return new ResponseEntity(apiResult, HttpStatus.UNAUTHORIZED);
        }

        // 判断是主账号还是子账号（经理/员工），返回不同的菜单
        ServiceResult<MenuTree> serviceResult;
        MenuTree menuTree;
        if (authenticationUser.getIsMain() != null && authenticationUser.getIsMain().equals(1)) {
            // 主账号默认：有所有菜单和按钮权限，除了系统管理-账号管理-人员管理
            menuTree = menuHandler.createMainAccountMenuTree();
            apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.TRUE);
            apiResult.setCode(HttpStatus.OK.value());
            apiResult.setMessage(ServiceResult.SELECT_SUCCESS);
            apiResult.setResult(menuTree);
        } else {
            // 子账号默认：根据权限返回对应的菜单列表
            serviceResult = menuTreeService.findByUserId(authenticationUser.getId());
            MenuTree result = serviceResult.getResult();
            if (result != null && result.getFirstMenuList() != null){
                //过滤没有选中的菜单
                List<Menu> menus = filterFirstMenuList(result.getFirstMenuList());
                if(CollectionUtils.isEmpty(menus)){
                    //没有任何权限但是能看首页
                    List<Menu> firstMenuListNew = new ArrayList<>();
                    Menu firstMenu = new Menu();
                    firstMenu.setId(MenuFirstEnum.HOME_PAGE.getId());
                    firstMenu.setName(MenuFirstEnum.HOME_PAGE.getName());
                    firstMenu.setType(MenuFirstEnum.HOME_PAGE.getMenuType());
                    firstMenu.setSelected(MenuSelected.YES);
                    firstMenu.setPath(MenuFirstEnum.HOME_PAGE.getPath());
                    firstMenu.setIcon(MenuFirstEnum.HOME_PAGE.getIcon());
                    firstMenuListNew.add(firstMenu);
                    result.setFirstMenuList(firstMenuListNew);
                }else {
                    result.setFirstMenuList(menus);
                }
            }else {
                result = new MenuTree();
                //没有任何权限但是能看首页
                List<Menu> firstMenuListNew = new ArrayList<>();
                Menu firstMenu = new Menu();
                firstMenu.setId(MenuFirstEnum.HOME_PAGE.getId());
                firstMenu.setName(MenuFirstEnum.HOME_PAGE.getName());
                firstMenu.setType(MenuFirstEnum.HOME_PAGE.getMenuType());
                firstMenu.setSelected(MenuSelected.YES);
                firstMenu.setPath(MenuFirstEnum.HOME_PAGE.getPath());
                firstMenu.setIcon(MenuFirstEnum.HOME_PAGE.getIcon());
                firstMenuListNew.add(firstMenu);
                result.setFirstMenuList(firstMenuListNew);
            }
            apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.TRUE);
            apiResult.setCode(HttpStatus.OK.value());
            apiResult.setMessage(ServiceResult.SELECT_SUCCESS);
            apiResult.setResult(result);
        }
        return new ResponseEntity<>(apiResult, HttpStatus.OK);
    }

    //过滤一级菜单
    public List<Menu> filterFirstMenuList(List<Menu> firstMenuList) {
        List<Menu> firstMenuListNew = new ArrayList<>();
        for (Menu firstMenu : firstMenuList) {
            //判断是否有二级菜单
            if (firstMenu.getChildMenuList() != null && firstMenu.getChildMenuList().size() > 0) {
                List<Menu> secondMenus = filterSecondMenuList(firstMenu.getChildMenuList());
                firstMenu.setChildMenuList(secondMenus);
                if (firstMenu.getSelected() == 1 || (firstMenu.getChildMenuList() != null && firstMenu.getChildMenuList().size() > 0)) {
                    firstMenuListNew.add(firstMenu);
                }
            } else {
                if (firstMenu.getSelected() == 1) {
                    firstMenuListNew.add(firstMenu);
                }
            }
        }
        return firstMenuListNew;
    }

    //过滤二级菜单
    public List<Menu> filterSecondMenuList(List<Menu> secondMenuList) {
        List<Menu> secondMenuListNew = new ArrayList<>();
        for (Menu secondMenu : secondMenuList) {
            //判断是否有三级菜单
            if (secondMenu.getChildMenuList() != null && secondMenu.getChildMenuList().size() > 0) {
                List<Menu> thirdMenus = filterThirdMenuList(secondMenu.getChildMenuList());
                secondMenu.setChildMenuList(thirdMenus);
                if (secondMenu.getSelected() == 1 || (secondMenu.getChildMenuList() != null && secondMenu.getChildMenuList().size() > 0)) {
                    secondMenuListNew.add(secondMenu);
                }
            } else {
                if (secondMenu.getSelected() == 1) {
                    secondMenuListNew.add(secondMenu);
                }
            }
        }
        return secondMenuListNew;
    }

    //过滤三级菜单
    public List<Menu> filterThirdMenuList(List<Menu> thirdMenuList) {
        List<Menu> thirdMenuListNew = new ArrayList<>();
        for (Menu thirdMenu : thirdMenuList) {
            if (thirdMenu.getSelected() == 1) {
                thirdMenuListNew.add(thirdMenu);
            }
        }
        return thirdMenuListNew;
    }
}